#ifndef NETCLIENT_H
#define NETCLIENT_H

#include <QObject>
#include <QNetworkAccessManager>
#include <QWebSocket>
#include <QProtobufSerializer>
#include <QNetworkReply>
#include <QNetworkRequest>
#include <QIODevice>
#include "../debug.h"
#include "base.qpb.h"
#include "friend.qpb.h"
#include "gateway.qpb.h"
#include "message_storage.qpb.h"
#include "message_transmit.qpb.h"
#include "notify.qpb.h"
#include "file.qpb.h"
#include "speech_recognition.qpb.h"
#include "user.qpb.h"
#include <QUuid>
#include "../model/data.h"

//前置声明
namespace model {
    class DataCenter;
} //end model

namespace netWork {

//创建唯一请求id
static QString makeRequestId();

class NetClient : public QObject
{
    Q_OBJECT
public:
    NetClient(model::DataCenter* dataCenter) : dataCenter(dataCenter)
    {
    }
    //ping方法
    void ping();
    //对QWebSocketClient进行初始化
    void initWebsocket();
    //发送身份认证请求
    void sendAuth();
    //////////////////////////////////////////////////////////////////////////////////////
    /// 请求/响应方法
    // 发送请求
    QNetworkReply* sendHttpRequest(const QString& apiPath,const QByteArray& body);

    //响应处理
    template<typename T>
    std::shared_ptr<T> handleHttpResponse(QNetworkReply* httpResp)
    {
        if(httpResp->error() != QNetworkReply::NoError)
        {
            LOG() << "httpResp 失败!";
            return std::shared_ptr<T>();
        }

        QByteArray body = httpResp->readAll();
        std::shared_ptr<T> respObj = std::make_shared<T>();
        respObj->deserialize(&pbSerializer,body);

        //判断是否出错
        if(!respObj->success())
        {
            LOG() << " requset_id = " << respObj->requestId() << " errmsg = " << respObj->errmsg();
            httpResp->deleteLater();
            return std::shared_ptr<T>();
        }

        LOG() << " requset_id = " << respObj->requestId() << " 响应完成 ";
        httpResp->deleteLater();
        return respObj;
    }
    //总推送逻辑处理
    void handleWsResponse(const bite_im::NotifyMessage& notifyMessage);
    //处理推送消息
    void handleWsMessage(const model::Message& message);
    //处理删除好友
    void handleWsRemoveFriend(const QString &userId);
    //处理申请好友
    void handleWsAddFriendApply(const model::UserInfo& userInfo);
    //处理好友申请结果
    void handleWsAddFriendProcess(const model::UserInfo& userInfo, bool agree);
    //处理群聊会话创建推送
    void handleWsSessionCreate(const model::ChatSessionInfo& chatSessionInfo);

    //////////////////////////////////////////////////////////////////////////////////////
    /// 网络通信数据方法
    //获取个人信息
    void getMyself(const QString& loginSessionId);
    //获取好友列表
    void getFriendList(const QString& loginSessionId);
    //获取消息列表
    void getChatSessionList(const QString& loginSessionId);
    //获取好友申请列表
    void getApplyList(const QString& loginSessionId);
    //获取历史消息列表
    void getRecentMessages(const QString& loginSessionId, const QString &chatSessionId, bool updateUI);
    //发送消息
    void sendMessage(const QString& loginSessionId, const QString &chatSessionId, const QByteArray& content, model::MessageType type, const QString& extraInfo);
    //收到消息
    void receiveMessage(const QString &chatSessionId);
    /// 个人用户信息修改
    //修改昵称
    void changeNickname(const QString& loginSessionId,const QString& nickname);
    //修改签名
    void changeDescription(const QString& loginSessionId,const QString& description);
    //获取验证码
    void getVerifyCode(const QString& phone);
    //更改电话号
    void changePhone(const QString loginSessionId, const QString& phone, const QString& verifyCodeId, const QString& verifyCode);
    //更改头像
    void changeAvatar(const QString loginSessionId,const QByteArray& avatar);
    /// 用户界面功能实现
    // 删除好友
    void deleteFriend(const QString& loginSessionId,const QString& userId);
    // 添加好友
    void addFriendApply(const QString& loginSessionId,const QString& userId);
    // 同意好友申请
    void acceptFriendApply(const QString& loginSessionId,const QString& userId);
    // 拒绝好友申请
    void rejectFriendApply(const QString& loginSessionId,const QString& userId);
    // 创建群聊会话
    void createGroupChatSession(const QString& loginSessionId,const QList<QString>& list);
    // 获取群聊会话成员列表
    void getMemberList(const QString& loginSessionId, const QString &chatSessionId);
    // 搜索好友结果
    void searchUser(const QString& loginSessionId, const QString &searchKey);

    // 搜索历史消息, 通过关键词
    void searchMessageBySearchKey(const QString& loginSessionId, const QString& chatSessionId, const QString &searchKey);

    void searchMessageByTime(const QString& loginSessionId, const QString& chatSessionId,const QDateTime &beginTime, const QDateTime &endTime);

    // 通过用户密码登录/注册
    void userLogin(const QString &username, const QString &password);
    void userRegister(const QString &username, const QString &password);

    // 通过电话号登录/注册
    void phoneLogin(const QString& phone,const QString& verifyCode);
    void phoneRegister(const QString& phone,const QString& verifyCode);

    ////////////////////////////////////////////////
    /// 异步获取文件内容
    ///////////////////////////////////////////////
    void getSingleFile(const QString &loginSessionId,const QString &fileId);

    ///语音转文字
    void speechConvertText(const QString &loginSessionId, const QString &fileId, const QByteArray& content);

private:

    model::DataCenter* dataCenter;
    QNetworkAccessManager httpClient;
    QWebSocket webSocketClient;
    QProtobufSerializer pbSerializer;

    QString HTTP_URL = "http://127.0.0.1:8000";
    QString WEBSOCKET_URL = "ws://127.0.0.1:8001/ws";
signals:
};




} // end namespace


#endif // NETCLIENT_H
